package com.itkjb.leisurely.center.sys.controller;

import com.itkjb.leisurely.authentication.core.common.properties.SecurityProperties;
import com.itkjb.leisurely.authentication.core.common.support.AuthenticationCache;
import com.itkjb.leisurely.authentication.core.common.utils.Oauth2TokenUtil;
import com.itkjb.leisurely.core.base.BaseResult;
import com.itkjb.leisurely.core.model.RequestUserInfoModel;
import com.itkjb.leisurely.core.util.Md5Utils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletRequest;
import java.security.Principal;
import java.util.List;
import java.util.Map;

/**
 * Copyright (C), 2021-2099
 *
 * @Author: lix
 * @Date: 2021/3/15 6:17 下午
 * @Description: token 相关controller
 * @Version: V1.0.0
 */
@Slf4j
@RestController
public class TokenController {


    @Autowired
    private TokenEndpoint tokenEndpoint;

    @Autowired
    SecurityProperties securityProperties;

    @Autowired
    AuthenticationCache authenticationCache;

    @ApiOperation(value="刷新token",notes="")
    @PostMapping("/oauth/token")
    public BaseResult<OAuth2AccessToken> RefreshToken(Principal principal, @RequestParam Map<String, String> parameters, ServletRequest request) {
        BaseResult<OAuth2AccessToken> res = new BaseResult<>();
        OAuth2AccessToken oAuth2AccessToken = null;
        // 原始tokenkey
        String oldTokenKey = null;
        // 从缓存器中获取 原始token 信息
        RequestUserInfoModel oldTokenInfo = null;
        try {
            oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
            oldTokenKey = Oauth2TokenUtil.getTokenKeyStringFromRequest(request);
            oldTokenInfo = authenticationCache.getUserInfoFromCatch(oldTokenKey);
        } catch (Exception e) {
            log.error("刷新token失败",e);
            res.setMsg("自动登录失败，请重新登录");
        }
        // 确保老的token 在缓存器中有效，新的token刷新也有效
        if(oldTokenInfo!=null && oAuth2AccessToken !=null && oAuth2AccessToken.getAdditionalInformation()!=null
                && "200".equals(oAuth2AccessToken.getAdditionalInformation().get("code"))){
            res.setData(oAuth2AccessToken);
            // 最新token key
            String tokenKey = Md5Utils.getMD5(oAuth2AccessToken.getValue());
            String userId = oldTokenInfo.getUserId();
            int exp = oAuth2AccessToken.getExpiresIn();
            List<String> permsCatchByTokenKey = authenticationCache.getPermsCatchByUserId(userId);
            List<String> rolesCatchByTokenKey = authenticationCache.getRolesCatchByUserId(userId);
            List<String> depsCatchByTokenKey = authenticationCache.getDepsCatchByUserId(userId);
            authenticationCache.setAuthenticationInfo(tokenKey,oldTokenInfo,rolesCatchByTokenKey,permsCatchByTokenKey,depsCatchByTokenKey,exp);
            // 清楚老的token
            authenticationCache.clearAuthenticationCache(oldTokenKey);
            res.toSuccess();
        }else{
            res.setMsg("自动登录失败，请重新登录");
        }
        return res;
    }
}
